home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / mpeg_play-2.1 / util.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  11KB  |  466 lines

  1. /*
  2.  * util.c --
  3.  *
  4.  *      Miscellaneous utility procedures.
  5.  *
  6.  */
  7.  
  8. /*
  9.  * Copyright (c) 1995 The Regents of the University of California.
  10.  * All rights reserved.
  11.  * 
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose, without fee, and without written agreement is
  14.  * hereby granted, provided that the above copyright notice and the following
  15.  * two paragraphs appear in all copies of this software.
  16.  * 
  17.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  18.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  19.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  20.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  21.  * 
  22.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  23.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  24.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  25.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  26.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  27.  */
  28.  
  29. #include <stdlib.h>
  30. #include "video.h"
  31. #include "proto.h"
  32. #include "util.h"
  33.  
  34. /* Declarations of global variables used. */
  35.  
  36. unsigned int curBits;
  37. int bitOffset;
  38. int bufLength;
  39. unsigned int *bitBuffer;
  40.  
  41. /* Bit masks used by bit i/o operations. */
  42.  
  43. unsigned int nBitMask[] = { 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 
  44.                 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, 
  45.                 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, 
  46.                 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 
  47.                 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, 
  48.                 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, 
  49.                 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 
  50.                 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe};
  51.  
  52. unsigned int bitMask[] = {  0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff, 
  53.                 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
  54.                 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
  55.                 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
  56.                 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
  57.                 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
  58.                 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
  59.                 0x0000000f, 0x00000007, 0x00000003, 0x00000001};
  60.  
  61. unsigned int rBitMask[] = { 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8, 
  62.                 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, 
  63.                 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, 
  64.                 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, 
  65.                 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, 
  66.                 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, 
  67.                 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, 
  68.                 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000};
  69.  
  70. unsigned int bitTest[] = {  0x80000000, 0x40000000, 0x20000000, 0x10000000, 
  71.                 0x08000000, 0x04000000, 0x02000000, 0x01000000,
  72.                 0x00800000, 0x00400000, 0x00200000, 0x00100000,
  73.                 0x00080000, 0x00040000, 0x00020000, 0x00010000,
  74.                 0x00008000, 0x00004000, 0x00002000, 0x00001000,
  75.                 0x00000800, 0x00000400, 0x00000200, 0x00000100,
  76.                 0x00000080, 0x00000040, 0x00000020, 0x00000010,
  77.                 0x00000008, 0x00000004, 0x00000002, 0x00000001};
  78.  
  79.  
  80. /*
  81.  *--------------------------------------------------------------
  82.  *
  83.  * correct_underflow --
  84.  *
  85.  *    Called when buffer does not have sufficient data to 
  86.  *      satisfy request for bits.
  87.  *      Calls get_more_data, an application specific routine
  88.  *      required to fill the buffer with more data.
  89.  *
  90.  * Results:
  91.  *      None really.
  92.  *  
  93.  * Side effects:
  94.  *    buf_length and buffer fields in curVidStream structure
  95.  *      may be changed.
  96.  *
  97.  *--------------------------------------------------------------
  98.  */
  99.  
  100. void 
  101. correct_underflow() {
  102.  
  103.   int status;
  104.  
  105.   status = get_more_data(&curVidStream->buf_start,
  106.              &curVidStream->max_buf_length,
  107.              &bufLength, &bitBuffer);
  108.  
  109.   if (status  < 0) {
  110.     if (!quietFlag) {
  111.       fprintf (stderr, "\n");
  112.       perror("Unexpected read error.");
  113.     }
  114.     exit(1);
  115.   }
  116.   else if ((status == 0) && (bufLength < 1)) {
  117.     if (!quietFlag) {
  118.       fprintf(stderr, "\nImproper or missing sequence end code.\n");
  119.     }
  120. #ifdef ANALYSIS
  121.     PrintAllStats();
  122. #endif
  123.     if (!quietFlag) {
  124.       PrintTimeInfo();
  125.     }
  126.  
  127.     if (loopFlag) {
  128.       clear_data_stream(&curVidStream->buf_start,
  129.             &curVidStream->max_buf_length,
  130.             &bufLength, &bitBuffer);      
  131.       longjmp(env, 1);
  132.     }
  133.     
  134.     DestroyVidStream(curVidStream);
  135.     exit(0);
  136.   }
  137. #ifdef UTIL2
  138.   curBits = *bitBuffer << bitOffset;
  139. #else
  140.   curBits = *bitBuffer;
  141. #endif
  142.  
  143. }
  144.  
  145.  
  146. /*
  147.  *--------------------------------------------------------------
  148.  *
  149.  * next_bits --
  150.  *
  151.  *    Compares next num bits to low order position in mask.
  152.  *      Buffer pointer is NOT advanced.
  153.  *
  154.  * Results:
  155.  *    TRUE, FALSE, or error code.
  156.  *
  157.  * Side effects:
  158.  *    None.
  159.  *
  160.  *--------------------------------------------------------------
  161.  */
  162.  
  163. int next_bits(num, mask)
  164. int num;
  165. unsigned int mask;
  166. {
  167.   unsigned int stream;
  168.   int ret_value;
  169.  
  170.   /* If no current stream, return error. */
  171.  
  172.   if (curVidStream == NULL)
  173.     return NO_VID_STREAM;
  174.  
  175.   /* Get next num bits, no buffer pointer advance. */
  176.  
  177.   show_bitsn(num, stream);
  178.  
  179.   /* Compare bit stream and mask. Set return value toTRUE if equal, FALSE if
  180.      differs. 
  181.   */
  182.  
  183.   if (mask == stream) {
  184.     ret_value = TRUE;
  185.   } else ret_value = FALSE;
  186.  
  187.   /* Return return value. */
  188.  
  189.   return ret_value;
  190. }
  191.  
  192.  
  193. /*
  194.  *--------------------------------------------------------------
  195.  *
  196.  * get_ext_data --
  197.  *
  198.  *    Assumes that bit stream is at begining of extension
  199.  *      data. Parses off extension data into dynamically 
  200.  *      allocated space until start code is hit. 
  201.  *
  202.  * Results:
  203.  *    Pointer to dynamically allocated memory containing
  204.  *      extension data.
  205.  *
  206.  * Side effects:
  207.  *    Bit stream irreversibly parsed.
  208.  *
  209.  *--------------------------------------------------------------
  210.  */
  211.  
  212. char *get_ext_data ()
  213. {
  214.   unsigned int size, marker;
  215.   char *dataPtr;
  216.   unsigned int data;
  217.  
  218.   /* Set initial ext data buffer size. */
  219.  
  220.   size = EXT_BUF_SIZE;
  221.  
  222.   /* Allocate ext data buffer. */
  223.  
  224.   dataPtr = (char *) malloc(size);
  225.  
  226.   /* Initialize marker to keep place in ext data buffer. */
  227.  
  228.   marker = 0;
  229.  
  230.   /* While next data is not start code... */
  231.   while (!next_bits(24, 0x000001)) {
  232.  
  233.     /* Get next byte of ext data. */
  234.  
  235.     get_bits8(data);
  236.  
  237.     /* Put ext data into ext data buffer. Advance marker. */
  238.  
  239.     dataPtr[marker] = (char) data;
  240.     marker++;
  241.  
  242.     /* If end of ext data buffer reached, resize data buffer. */
  243.  
  244.     if (marker == size) {
  245.       size += EXT_BUF_SIZE;
  246.       dataPtr = (char *) realloc(dataPtr, size);
  247.     }
  248.   }
  249.  
  250.   /* Realloc data buffer to free any extra space. */
  251.  
  252.   dataPtr = (char *) realloc(dataPtr, marker);
  253.  
  254.   /* Return pointer to ext data buffer. */
  255.  
  256.   return dataPtr;
  257. }
  258.  
  259.  
  260. /*
  261.  *--------------------------------------------------------------
  262.  *
  263.  * next_start_code --
  264.  *
  265.  *    Parses off bitstream until start code reached. When done
  266.  *      next 4 bytes of bitstream will be start code. Bit offset
  267.  *      reset to 0.
  268.  *
  269.  * Results:
  270.  *    Status code.
  271.  *
  272.  * Side effects:
  273.  *    Bit stream irreversibly parsed.
  274.  *
  275.  *--------------------------------------------------------------
  276.  */
  277.  
  278. int next_start_code()
  279. {
  280.   int state;
  281.   int byteoff;
  282.   unsigned int data;
  283.  
  284.   /* If no current stream, return error. */
  285.  
  286.   if (curVidStream == NULL)
  287.     return NO_VID_STREAM;
  288.  
  289.   /* If insufficient buffer length, correct underflow. */
  290.  
  291.   if (bufLength < 4) {
  292.     correct_underflow();
  293.   }
  294.  
  295.   /* If bit offset not zero, reset and advance buffer pointer. */
  296.  
  297.   byteoff = bitOffset % 8;
  298.  
  299.   if (byteoff != 0) {
  300.     flush_bits((8-byteoff));
  301.   }
  302.  
  303.   /* Set state = 0. */
  304.  
  305.   state = 0;
  306.  
  307.   /* While buffer has data ... */
  308.  
  309.   while(bufLength > 0) {
  310.  
  311.     /* If insufficient data exists, correct underflow. */
  312.  
  313.     if (bufLength < 4) {
  314.       correct_underflow();
  315.     }
  316.  
  317.     /* If next byte is zero... */
  318.  
  319.     get_bits8(data);
  320.  
  321.     if (data == 0) {
  322.  
  323.       /* If state < 2, advance state. */
  324.  
  325.       if (state < 2) state++;
  326.     }
  327.  
  328.     /* If next byte is one... */
  329.  
  330.     else if (data == 1) {
  331.  
  332.       /* If state == 2, advance state (i.e. start code found). */
  333.  
  334.       if (state == 2) state++;
  335.  
  336.       /* Otherwise, reset state to zero. */
  337.  
  338.       else state = 0;
  339.     }
  340.  
  341.     /* Otherwise byte is neither 1 or 0, reset state to 0. */
  342.  
  343.     else {
  344.       state = 0;
  345.     }
  346.  
  347.     /* If state == 3 (i.e. start code found)... */
  348.  
  349.     if (state == 3) {
  350.  
  351.       /* Set buffer pointer back and reset length & bit offsets so
  352.        * next bytes will be beginning of start code. 
  353.        */
  354.  
  355.       bitOffset = bitOffset - 24;
  356.  
  357. #ifdef ANALYSIS
  358.       bitCount -= 24;
  359. #endif
  360.  
  361.       if (bitOffset < 0) {
  362.         bitOffset = 32 + bitOffset;
  363.         bufLength++;
  364.         bitBuffer--;
  365. #ifdef UTIL2
  366.         curBits = *bitBuffer << bitOffset;
  367. #else
  368.         curBits = *bitBuffer;
  369. #endif
  370.       }
  371.       else {
  372. #ifdef UTIL2
  373.         curBits = *bitBuffer << bitOffset;
  374. #else
  375.         curBits = *bitBuffer;
  376. #endif
  377.       }
  378.  
  379.       /* Return success. */
  380.  
  381.       return OK;
  382.     }
  383.   }
  384.  
  385.   /* Return underflow error. */
  386.  
  387.   return STREAM_UNDERFLOW;
  388. }
  389.  
  390.  
  391. /*
  392.  *--------------------------------------------------------------
  393.  *
  394.  * get_extra_bit_info --
  395.  *
  396.  *    Parses off extra bit info stream into dynamically 
  397.  *      allocated memory. Extra bit info is indicated by
  398.  *      a flag bit set to 1, followed by 8 bits of data.
  399.  *      This continues until the flag bit is zero. Assumes
  400.  *      that bit stream set to first flag bit in extra
  401.  *      bit info stream.
  402.  *
  403.  * Results:
  404.  *    Pointer to dynamically allocated memory with extra
  405.  *      bit info in it. Flag bits are NOT included.
  406.  *
  407.  * Side effects:
  408.  *    Bit stream irreversibly parsed.
  409.  *
  410.  *--------------------------------------------------------------
  411.  */
  412.  
  413. char *get_extra_bit_info ()
  414. {
  415.   unsigned int size, marker;
  416.   char *dataPtr;
  417.   unsigned int data;
  418.  
  419.   /* Get first flag bit. */
  420.   get_bits1(data);
  421.  
  422.   /* If flag is false, return NULL pointer (i.e. no extra bit info). */
  423.  
  424.   if (!data) return NULL;
  425.  
  426.   /* Initialize size of extra bit info buffer and allocate. */
  427.  
  428.   size = EXT_BUF_SIZE;
  429.   dataPtr = (char *) malloc(size);
  430.  
  431.   /* Reset marker to hold place in buffer. */
  432.  
  433.   marker = 0;
  434.  
  435.   /* While flag bit is true. */
  436.  
  437.   while (data) {
  438.  
  439.     /* Get next 8 bits of data. */
  440.     get_bits8(data);
  441.  
  442.     /* Place in extra bit info buffer. */
  443.  
  444.     dataPtr[marker] = (char) data;
  445.     marker++;
  446.  
  447.     /* If buffer is full, reallocate. */
  448.  
  449.     if (marker == size) {
  450.       size += EXT_BUF_SIZE;
  451.       dataPtr = (char *) realloc(dataPtr, size);
  452.     }
  453.  
  454.     /* Get next flag bit. */
  455.     get_bits1(data);
  456.   }
  457.  
  458.   /* Reallocate buffer to free extra space. */
  459.  
  460.   dataPtr = (char *) realloc(dataPtr, marker);
  461.  
  462.   /* Return pointer to extra bit info buffer. */
  463.  
  464.   return dataPtr;
  465. }
  466.